<template>
  <!--地图挂载dom-->
  <div id="map">
    <div class="tool">
      <el-button @click="startAnimation">开始</el-button>
      <el-button @click="stopAnimation">停止</el-button>
      <el-slider
        @change="handleSpeed"
        v-model="speed"
        height="200px">
      </el-slider>
    </div>
  </div>
</template>

<script setup>
//引入依赖
import {Feature, Map, View} from 'ol'
import {OSM, Vector as VectorSource} from 'ol/source'
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import {LineString} from 'ol/geom';
import {Fill, Stroke, Style, Icon, Circle as CircleStyle} from 'ol/style';
import {getVectorContext} from "ol/render";
import Point from 'ol/geom/Point';
import {ref, onMounted} from 'vue'
import image from '../data/icon.png';
import XYZ from "ol/source/XYZ.js";

let geom = null;
let position = null;
let styles  = {
  'route': new Style({
    stroke: new Stroke({
      width: 6,
      color: [237, 212, 0, 0.8],
    }),
  }),
  'icon': new Style({
    image: new Icon({
      anchor: [0.5, 1],
      src: image,
    }),
  }),
  'geoMarker': new Style({
    image: new CircleStyle({
      radius: 7,
      fill: new Fill({color: 'black'}),
      stroke: new Stroke({
        color: 'white',
        width: 2,
      }),
    }),
  }),
};
let geoMarker = null;
let vectorLayer = null;
//地图路线的初始值
const coordinates = [
  [
    114.27429199218749,
    30.5717205651999
  ],
  [
    113.92822265625,
    29.267232865200878
  ],
  [
    113.92822265625,
    28.57487404744697
  ],
  [
    113.79638671875,
    27.46928747369202
  ],
  [
    113.73046875,
    26.941659545381516
  ],
  [
    113.8623046875,
    26.017297563851745
  ],
  [
    113.62060546875,
    24.686952411999155
  ],
  [
    113.4228515625,
    23.745125865762923
  ],
  [
    113.291015625,
    23.120153621695614
  ],
  [
    113.258056640625,
    23.117627611920557
  ]
]
const map = ref(null);
const distance = ref(0);
const speed = ref(1);
const animating = ref(false);
const lastTime = ref(0);

const addLineWithPoints = (coordinates) => {
  geom = new LineString(coordinates);
  const routeFeature = new Feature({
    type: 'route',
    geometry: geom,
  });

  //开始的要素
  const startMarker = new Feature({
    type: 'icon',
    geometry: new Point(geom.getFirstCoordinate()),
  });
  //结束的要素
  const endMarker = new Feature({
    type: 'icon',
    geometry: new Point(geom.getLastCoordinate()),
  });

  position = startMarker.getGeometry().clone();
  //移动的点
  geoMarker = new Feature({
    type: 'geoMarker',
    geometry: position,
  });

  vectorLayer = new VectorLayer({
    source: new VectorSource({
      features: [routeFeature, startMarker, endMarker, geoMarker]
    }),
    style: function(feature) {
      return styles[feature.get('type')]
    }
  })
  map.value.addLayer(vectorLayer);
}

const moveFeature = event =>{
  //每一帧渲染的时间
  const time = event.frameState.time;
  //上一帧与当前帧渲染的时间差
  const elapsedTime = time - lastTime.value;
  //通过上一帧与当前帧渲染时的时间差计算出当前坐标需要移动的距离
  //计算距离的distance保持数据再0与1之间，不断自增
  distance.value = (distance.value + (speed.value * elapsedTime) / 1e6) % 2;
  // 返回沿线串提供的分数处的坐标
  // 是一个介于 0 和 1 之间的小数
  // 其中 0 是线串的开始，1 是结束
  const currentCoordinate = geom.getCoordinateAt(
    distance.value > 1 ? 2 - distance.value : distance.value
  );

  if (distance.value > 1){
    stopAnimation();
  }

  //当前的坐标设置到移动的marker
  position.setCoordinates(currentCoordinate);
  //获取到渲染事件的上下文对象
  const vectorContext = getVectorContext(event);
  //给移动的marker设置样式
  vectorContext.setStyle(styles.geoMarker);
  //使用渲染事件的上下文对象，绘制geometry
  vectorContext.drawGeometry(position);

  // 手动渲染
  map.value.render();
  lastTime.value = time;
}

const stopAnimation = () => {
  animating.value = false;
  geoMarker.setGeometry(position);//移动的marker就当前移动点的位置
  vectorLayer.un('postrender', moveFeature)
}

const startAnimation = ()=> {
  animating.value = true;
  lastTime.value = Date.now();//当前时间
  vectorLayer.on('postrender', moveFeature);//渲染时监听
  //将移动到哪个地方的点置空
  geoMarker.setGeometry(null);
}

const handleSpeed = (value) => {
  speed.value = value;
}

onMounted(()=>{
    map.value = new Map({
      target:'map',
      layers: [
        new TileLayer({
          source: new XYZ({url: "http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=d30d1c34260f2edc72b25f9985e2fd69"}),
        })
      ],
      //配置视图
      view: new View({
        center: [113.24981689453125, 26.126468438108688],   //视图中心位置
        projection: "EPSG:4326", //指定投影
        zoom: 5   //缩放到的级别
      })
    })

  addLineWithPoints(coordinates)
})



</script>

<style scoped>
#map {
  width: 100%;
  height: 100%;
}

.tool {
  position: absolute;
  top: 50px;
  right: 50px;
  z-index: 9999;
}
</style>
